package com.cet.juc;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @program: cet-practice
 * @description:
 * @author: 陈恩涛
 * @create: 2023-07-02 15:53
 **/
public class MultiThreadPrintTest {

    public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(3);
        AtomicInteger count = new AtomicInteger(0);
        CompletableFuture.runAsync(() -> {
            while (true) {
                // 自旋等待
                if (count.get() % 2 != 0 ) {
                    continue;
                }
                if (count.get() < 100) {
                    System.out.println("a");
                    count.getAndIncrement();
                } else {
                    try {
                        // 让另一个线程最后的自旋解锁
                        count.getAndIncrement();
                        barrier.await();
                    } catch (InterruptedException | BrokenBarrierException e) {
                        throw new RuntimeException(e);
                    }
                    return;
                }
            }
        });
        CompletableFuture.runAsync(() -> {
            while (true) {
                // 自旋等待
                if (count.get() % 2 != 1 ) {
                    continue;
                }
                if (count.get() < 100) {
                    System.out.println("b");
                    count.getAndIncrement();
                } else {
                    try {
                        barrier.await();
                    } catch (InterruptedException | BrokenBarrierException e) {
                        throw new RuntimeException(e);
                    }
                    return;
                }
            }
        });
        try {
            barrier.await();
        } catch (InterruptedException | BrokenBarrierException e) {
            throw new RuntimeException(e);
        }
        System.out.println("执行结束");
    }

//    public static void main(String[] args) {
//        PrintObject printObject = new PrintObject(true, 50);
//
//        new Thread(() -> {
//            printObject.print("A", true);
//        }).start();
//
//        new Thread(() -> {
//            printObject.print("B", false);
//        }).start();
//    }

}

class PrintObject{

    private boolean flag;

    private final int loopNum;

    public PrintObject(boolean flag, int loopNum) {

        this.flag = flag;
        this. loopNum = loopNum;
    }

    public void print(String str, boolean curFlag) {
        for (int i = 0; i < loopNum; i++) {
            synchronized (this) {
                while (curFlag != flag) {
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }

                System.out.println(str);
                flag = !flag;
                this.notifyAll();
            }
        }
    }
}
